package ro.upt.ac.cstaicu.instrumentation;

import java.util.ArrayList;

import org.objectweb.asm.ClassWriter;

import ro.upt.ac.cstaicu.instrumentation.classadapters.CustomClassAdapter;
import ro.upt.ac.cstaicu.instrumentation.classadapters.IMAllMethodsCA;
import ro.upt.ac.cstaicu.instrumentation.classadapters.IMMethodsFilterCA;

/**
 * It creates a {@link CustomClassAdapter} depending on the chosen
 * implementation type. It is a singleton class.
 * 
 * @author Cristian-Alexandru STAICU
 * 
 */
public class AdapterFactory {

	/**
	 * stores the global instance of the factory.
	 */
	private static AdapterFactory instance = null;

	/**
	 * It ensures that the object instances are created just locally
	 */
	private AdapterFactory() {
	};

	/**
	 * if the instance field is not yet initialized it instantiate an
	 * {@link AdapterFactory} object and stores it as the instance.
	 * 
	 * @return the single, global instance of the class.
	 */
	public static AdapterFactory getInstance() {
		if (instance == null)
			instance = new AdapterFactory();
		return instance;
	}

	/**
	 * Return an adapter that traces all the predicate in the class.
	 * 
	 * @param wrappedVisitor
	 *            - the Writer class that receives the calls from the adapter.
	 * @return an {@link IMAllMethodsCA} adapter
	 */
	public CustomClassAdapter getClassPredicateTracerAdapter(
			ClassWriter wrappedVisitor) {
		return new IMAllMethodsCA(wrappedVisitor);
	}

	/**
	 * Return an adapter that traces just the predicates in the desire methods.
	 * 
	 * @param wrappedVisitor
	 *            - the Writer class that receives the calls from the adapter.
	 * @param desiredMethods
	 *            - a list of method names that should be instrumented.
	 * @return an {@link IMAllMethodsCA} adapter
	 */
	public CustomClassAdapter getMethodsFilterPredicateAdapter(
			ClassWriter wrappedVisitor, ArrayList<String> desiredMethods) {
		return new IMMethodsFilterCA(wrappedVisitor, desiredMethods);
	}

}
